package com.dc.project.service.impl;

import com.dc.project.entity.bo.TaskResultGenerateBo;
import com.dc.project.entity.map.TaskResultGenerateMapVo;
import com.dc.project.entity.po.TaskDetail;
import com.dc.project.entity.po.TaskDetailItem;
import com.dc.project.entity.po.TaskResultGenerate;
import com.dc.project.entity.query.TaskResultGenerateQuery;
import com.dc.project.entity.vo.TaskResultGenerateVo;
import com.dc.project.mapper.TaskResultGenerateMapper;
import com.dc.project.service.TaskDetailItemService;
import com.dc.project.service.TaskDetailService;
import com.dc.project.service.TaskResultGenerateService;
import com.dc.project.service.TaskService;
import com.dc.project.util.TaskGenerateUtil;
import com.own.business.resource.business.service.FileRecordService;
import com.own.business.resource.business.service.ResourceService;
import com.own.business.resource.common.model.UploadModelConfig;
import com.own.business.resource.entity.po.FileRecord;
import com.own.business.resource.entity.vo.FileRecordVo;
import com.own.compoent.util.zip.util.ZipUtil;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * TaskResultGenerateServiceImpl
 *
 * @author chenxueli
 * @date 2025-03-10 16:37:53
 */
@Slf4j
@Service
public class TaskResultGenerateServiceImpl extends AbstractBaseService<
        TaskResultGenerate,
        TaskResultGenerateBo,
        TaskResultGenerateVo,
        TaskResultGenerateMapVo,
        TaskResultGenerateQuery,
        TaskResultGenerateMapper
        > implements TaskResultGenerateService {

    @Resource
    private TaskResultGenerateMapper taskResultGenerateMapper;

    @Resource
    private TaskService taskService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private TaskDetailItemService taskDetailItemService;
    @Resource
    private ResourceService resourceService;
    @Resource
    private FileRecordService fileRecordService;

    @Resource
    private TaskGenerateUtil taskGenerateUtil;

    /**
     * 根据任务id查询所有生成的文件信息
     *
     * @param taskId 任务id
     * @return 生成的文件信息
     */
    @Override
    public List<TaskResultGenerate> listByTaskId(Long taskId) {
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkTaskId, taskId);
        return listByWrapper(wrapper);
    }

    /**
     * 根据项id生成文件
     *
     * @param itemId 项id
     */
    @Override
    public void generateByItemId(Long itemId) {
        // 获取信息
        var item = taskDetailItemService.getPoById(itemId);
        // 删除这个项下的所有生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkItemId, itemId);
        taskResultGenerateMapper.delete(wrapper);
        // 将内容设置为等待中
        taskDetailItemService.updateStatusByItemId(itemId, TaskDetailItem.GenerateStatus.WAITING);
        // 执行生成文件
        taskGenerateUtil.start();
    }

    /**
     * 根据详情id生成文件
     *
     * @param detailId 详情id
     */
    @Override
    public void generateByDetailId(Long detailId) {
        var detail = taskDetailService.getPoById(detailId);
        // 删除这个详情下的所有生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkDetailId, detailId);
        taskResultGenerateMapper.delete(wrapper);
        // 将内容设置为等待中
        taskDetailItemService.updateStatusByDetailId(detailId, TaskDetailItem.GenerateStatus.WAITING);
        // 执行生成文件
        taskGenerateUtil.start();
    }

    /**
     * 根据任务id生成文件
     *
     * @param taskId 任务id
     */
    @Override
    public void generateByTaskId(Long taskId) {
        // 删除这个任务下的所有生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkTaskId, taskId);
        taskResultGenerateMapper.delete(wrapper);
        // 将内容设置为等待中
        taskDetailItemService.updateStatusByTaskId(taskId, TaskDetailItem.GenerateStatus.WAITING);
        // 执行生成文件
        taskGenerateUtil.start();
    }

    /**
     * 根据项id打包生成文件信息
     *
     * @param itemId 项id
     * @return 打包后上传的文件
     */
    @Override
    public FileRecordVo packageByItemId(Long itemId) {
        // 查询这个项的名称
        var item = taskDetailItemService.getPoById(itemId);
        // 查询所有的生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkItemId, itemId);
        var list = listByWrapper(wrapper);
        var folder = "/tmp/" + UUID.randomUUID() + File.separator + item.getTitle();
        // 进行文件下载
        list.forEach(temp -> FileUtil.downloadFile(temp.getFilePath(), folder + File.separator, temp.getFileName()));
        // 将文件打包压缩
        var zipPath = ZipUtil.compress.compress(folder);
        // 将文件上传到对应的位置（返回结果）
        var fileRecord = resourceService.upload(zipPath, UploadModelConfig.NOT_RANDOM_NAME);
        // 删除生成的临时文件信息（压缩包也在临时文件夹中）
        FileUtil.deleteFile(new File(folder));
        return fileRecord;
    }

    /**
     * 根据详情id打包生成文件信息
     *
     * @param detailId 详情id
     * @return 打包后上传的文件
     */
    @Override
    public FileRecordVo packageByDetailId(Long detailId) {
        // 查询详情的信息
        var detail = taskDetailService.getPoById(detailId);
        // 查询所有的item信息
        var itemList = taskDetailItemService.listByDetailId(detailId);
        // 查询所有的生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkDetailId, detailId);
        var generateList = listByWrapper(wrapper);
        var generateMap = generateList.stream().collect(Collectors.groupingBy(TaskResultGenerate::getFkItemId));
        // 获取文件信息
        var detailFileRecord = fileRecordService.getPoById(detail.getFkFileId(), false);
        var detailFileName = FileUtil.extractFileNameFromUrl(detailFileRecord != null ? detailFileRecord.getOldName() : detail.getFilePath(), false);
        // 创建文件夹
        var folder = "/tmp/" + UUID.randomUUID() + File.separator + (StringUtils.isBlank(detailFileName) ? detail.getTitle() : detailFileName);
        for (int i = 0; i < itemList.size(); i++) {
            var item = itemList.get(i);
            var tempList = generateMap.get(item.getId());
            if (tempList != null) {
                var tempFolder = folder + File.separator + (i + 1) + "、" + item.getTitle() + File.separator;
                // 进行文件下载
                tempList.forEach(temp -> FileUtil.downloadFile(temp.getFilePath(), tempFolder, temp.getFileName()));
            }
        }
        // 将文件打包压缩
        var zipPath = ZipUtil.compress.compress(folder);
        // 将文件上传到对应的位置（返回结果）
        var fileRecord = resourceService.upload(zipPath, UploadModelConfig.NOT_RANDOM_NAME);
        // 删除生成的临时文件信息（压缩包也在临时文件夹中）
        FileUtil.deleteFile(new File(folder));
        return fileRecord;
    }

    /**
     * 根据任务id打包生成文件信息
     *
     * @param taskId 任务id
     * @return 打包后上传的文件
     */
    @Override
    public FileRecordVo packageByTaskId(Long taskId) {
        // 获取任务信息
        var task = taskService.getPoById(taskId);
        // 获取详情信息
        var detailList = taskDetailService.listByTaskId(taskId);
        // 查询详情的文件信息
        var fileRecordIdList = detailList.stream().map(TaskDetail::getFkFileId).toList();
        var fileRecordList = fileRecordService.listByIdList(fileRecordIdList);
        var fileRecordMap = fileRecordList.stream().collect(Collectors.toMap(FileRecord::getId, Function.identity()));
        // 获取详情项信息
        var itemList = taskDetailItemService.listByTaskId(taskId);
        var itemMap = itemList.stream().collect(Collectors.groupingBy(TaskDetailItem::getFkDetailId));
        // 查询所有的生成文件信息
        var wrapper = lambdaQueryWrapper().eq(TaskResultGenerate::getFkTaskId, taskId);
        var generateList = listByWrapper(wrapper);
        var generateMap = generateList.stream().collect(Collectors.groupingBy(TaskResultGenerate::getFkItemId));
        // 创建文件夹
        var folder = "/tmp/" + UUID.randomUUID() + File.separator + task.getCompanyName() + "-" + task.getTitle();
        detailList.forEach(detail -> {
            var fileRecord = fileRecordMap.get(detail.getFkFileId());
            var fileName = FileUtil.extractFileNameFromUrl(fileRecord != null ? fileRecord.getOldName() : detail.getFilePath(), false);
            var detailFolder = folder + File.separator + fileName + File.separator;
            var tempItemList = itemMap.get(detail.getId());
            for (int i = 0; i < tempItemList.size(); i++) {
                var item = tempItemList.get(i);
                var tempList = generateMap.get(item.getId());
                if (tempList != null) {
                    var tempFolder = detailFolder + (i + 1) + "、" + item.getTitle() + File.separator;
                    // 进行文件下载
                    tempList.forEach(temp -> FileUtil.downloadFile(temp.getFilePath(), tempFolder, temp.getFileName()));
                }
            }
        });
        // 将文件打包压缩
        var zipPath = ZipUtil.compress.compress(folder);
        // 将文件上传到对应的位置（返回结果）
        var fileRecord = resourceService.upload(zipPath, UploadModelConfig.NOT_RANDOM_NAME);
        // 删除生成的临时文件信息（压缩包也在临时文件夹中）
        FileUtil.deleteFile(new File(folder));
        return fileRecord;
    }

}
